/*
 * CatManagertest.cpp
 *
 *  Created on: Apr 9, 2014
 *      Author: GuoWei
 */

#include "Cats/CatsManager.h"
#include "Cats/PunkCat.h"
#include "Map/GameMap.h"
#include "Character/Character.h"
#include "GameManager.h"
#include "src/TestMacros.h"
#include "src/CheckMacros.h"
#include "src/TestRunner.h"
#include "src/TimeConstraint.h"
#include "src/ReportAssert.h"

using namespace UnitTest;

SUITE(CatsManager)
{
	TEST(CatsManagerInitialized)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		bool isCatsInitialized = myCatsManager->returnCats() != NULL;
		CHECK_EQUAL(isCatsInitialized, true);

		//cleanup
		CatsManager::deleteInstance();
	}

	TEST(CatsManagerDestructed)
	{
		//create cats manager
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0,GameMap::getInstance(), Character::getInstance(), new GameManager());
		myCatsManager = 0;

		//destroy cats manager and assert
		CatsManager::deleteInstance();
		myCatsManager = CatsManager::getInstance();
		bool isCatsInitialized = myCatsManager->returnCats() != NULL;
		CHECK_EQUAL(isCatsInitialized, false);
	}

	TEST(CatsManagerAdditionalCat1)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		PunkCat* cat = PunkCat::createCat();
		myCatsManager->addCat(cat);
		myCatsManager->update(0.01);

		bool isCatAdded = myCatsManager->returnCats()->count() == 1;
		CHECK_EQUAL(isCatAdded, true);
	}

	TEST(CatsManagerAdditionalCatN)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		//test N cats
		for(int i = 0; i < 3; i++)
		{
			PunkCat* tempCat = PunkCat::createCat();
			myCatsManager->addCat(tempCat);
		}
		myCatsManager->update(0.01);
		bool isCatAdded = myCatsManager->returnCats()->count() == 3;
		CHECK_EQUAL(isCatAdded, true);
	}

	//TEST(CatsManagerAdditionalCatNull)

	TEST(CatsManagerDamageAllSwipedCatsN)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		int numberOfCats = 2;
		//create multiple cats with swiped property
		for (int i = 0; i < numberOfCats; i++)
		{
			PunkCat* tempCat = PunkCat::createCat();
			tempCat->setIsSwiped(true);
			//add to cats Manager
			myCatsManager->addCat(tempCat);
		}
		myCatsManager->update(0.001);

		//damage the cat
		myCatsManager->damageAllSwipedCats();

		CCArray* cats = myCatsManager->returnCats();
		bool healthReduced = true;
		for (int i = 0; i < cats->count(); i++)
		{
			BaseCat* cat = (BaseCat*)cats->objectAtIndex(i);
			if (cat->getHealthReduction() == 0)
			{
				healthReduced = false;
				break;
			}
		}
		CHECK_EQUAL(healthReduced, true);
	}

	TEST(CatsManagerCheckTouchCollision0)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		bool touchCollided = myCatsManager->checkCatTouchCollision(CCPoint(0,0)) == 0;
		CHECK_EQUAL(touchCollided, true);
	}

	TEST(CatsManagerCheckTouchCollision1)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		PunkCat* cat1 = PunkCat::createCat();
		cat1->setPosition(CCPoint(1,1));

		myCatsManager->addCat(cat1);
		myCatsManager->update(0.001);

		bool touchCollided = myCatsManager->checkCatTouchCollision(CCPoint(0,0)) == 1;

		CHECK_EQUAL(touchCollided, true);
	}

	TEST(CatsManagerCheckTouchCollisionN)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		PunkCat* cat1 = PunkCat::createCat();
		cat1->setPosition(CCPoint(10,10));
		myCatsManager->addCat(cat1);

		PunkCat* cat2 = PunkCat::createCat();
		cat2->setPosition(CCPoint(800, 800));
		myCatsManager->addCat(cat2);

		PunkCat* cat3 = PunkCat::createCat();
		cat3->setPosition(CCPoint(20,20));
		myCatsManager->addCat(cat3);

		myCatsManager->update(0.001);

		bool touchCollided = myCatsManager->checkCatTouchCollision(CCPoint(15, 15)) == 2;
		CHECK_EQUAL(touchCollided, true);
	}

	TEST(CatsManagerUpdateDirectorSpeed)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		float speedMulti1 = 1.0;
		float speedMulti2 = 2.0;
		float newMultiplier = 2.1;
		PunkCat* cat1 = PunkCat::createCat();
		cat1->setSpeedMultiplier(speedMulti1);
		myCatsManager->addCat(cat1);

		PunkCat* cat2 = PunkCat::createCat();
		cat2->setSpeedMultiplier(speedMulti2);
		myCatsManager->addCat(cat2);

		myCatsManager->update(0.001);

		//check normal update
		myCatsManager->updateDirectorSpeed(newMultiplier);
		bool speedUpdated = (cat1->getSpeedMultiplier() == (speedMulti1 * newMultiplier)) &&
							(cat2->getSpeedMultiplier() == (speedMulti2 * newMultiplier));
		CHECK_EQUAL(speedUpdated, true);

		//check lower limit
		float lowerLimit = -1;
		cat1->setSpeedMultiplier(1.0); //reset the multiplier
		cat2->setSpeedMultiplier(1.0); //reset the multiplier
		myCatsManager->updateDirectorSpeed(lowerLimit);
		speedUpdated = (cat1->getSpeedMultiplier() == 1.0 * lowerLimit) ||
						(cat2->getSpeedMultiplier() == 1.0 * lowerLimit);
		CHECK_EQUAL(speedUpdated, false);
	}

	TEST(CatsManagerUpdateDirectorObstacle)
	{
		CatsManager* myCatsManager = CatsManager::getInstance();
		myCatsManager->init(0, GameMap::getInstance(), Character::getInstance(), new GameManager());

		int obstacleChance1 = 10;
		int obstacleChance2 = 20;
		int newChance = 90;
		PunkCat* cat1 = PunkCat::createCat();
		cat1->setObstacleHitChance(obstacleChance1);
		myCatsManager->addCat(cat1);

		PunkCat* cat2 = PunkCat::createCat();
		cat2->setObstacleHitChance(obstacleChance2);
		myCatsManager->addCat(cat2);

		myCatsManager->update(0.001);

		//check correct update
		myCatsManager->updateDirectorObstacle(newChance);
		bool obstacleChanceUpdated = (cat1->getObstacleHitChance() == newChance) &&
									(cat2->getObstacleHitChance() == newChance);
		CHECK_EQUAL(obstacleChanceUpdated, true);

		//check over limit update
		float upperLimit = 101;
		myCatsManager->updateDirectorObstacle(upperLimit);
		obstacleChanceUpdated = (cat1->getObstacleHitChance() == upperLimit) ||
								(cat2->getObstacleHitChance() == upperLimit);
		CHECK_EQUAL(obstacleChanceUpdated, false);

		//check lower limit
		float lowerLimit = -1;
		myCatsManager->updateDirectorObstacle(lowerLimit);
		obstacleChanceUpdated = (cat1->getObstacleHitChance() == lowerLimit) ||
								(cat2->getObstacleHitChance() == lowerLimit);
		CHECK_EQUAL(obstacleChanceUpdated, false);
	}
}


